package models.System.Systems;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import javassist.NotFoundException;
import org.junit.Test;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.oned.Code128Writer;
import play.Play;

public class QR_code {
    static class ImageFormat {
        static final String PNG = "png";
        static final String GIF = "gif";
        static final String BMP = "bmp";
        static final String JPEG = "jpeg";
    }

    @Test
    public static void qrcodeBuildTest(String outName, String contents) {
        QR_code.qrCodeBuild(contents,Play.applicationPath+"/public/images", outName, ImageFormat.PNG, 200, 200);
    }

    @Test
    public void barCodeBuildTest() {
        // 输出目录
        String outPath = "d:\\QR_code\\";
        // 输出文件名
        String outName = "zxingQR_code.png";
        // 生成内容
        String contents = "barCode QR_code";
        QR_code.barCodeBuild(contents, outPath, outName, ImageFormat.PNG, 180, 60);
    }

    @Test
    public void qrCodeParseTest() {
        // String content = QR_code.qrcodeParse("d:\\QR_code\\zxingQR_code.png");
        String content = QR_code.qrcodeParse(
                "http://dl2.iteye.com/upload/attachment/0103/0259/f1c4cf6c-c825-3504-8c9e-97019e3796d1.png");
        System.out.println(null == content ? "解析失败" : content);
    }

    /**
     * 二维码生成
     *
     * @param contents
     *            文本内容
     * @param outPath
     *            输出目录
     * @param outName
     *            输出文件
     * @param format
     *            输出文件类型(png,jpeg...)
     * @param width
     *            生成图片宽度
     * @param height
     *            生成图片高度
     */
    public static void qrCodeBuild(String contents, String outPath, String outName, String format, int width,
                                   int height) {
        try {
            // 输出目录检测
            if (!new File(outPath).exists()) {
                new File(outPath).mkdirs();
            }
            Path path = FileSystems.getDefault().getPath(outPath, outName);

            // 相关配置(编码、白边)
            Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            hints.put(EncodeHintType.MARGIN, 1);

            // 生成
            BitMatrix matrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);

            // 输出二维码
            MatrixToImageConfig config = new MatrixToImageConfig(0xFF000000, 0xFFFFFFFF);
            MatrixToImageWriter.writeToPath(matrix, format, path, config);
            // 输出为文件流(Web项目)
            // OutputStream stream = response.getOutputStream();
            // MatrixToImageWriter.writeToStream(matrix, format, stream,config);

            System.out.println("调试输出:OK");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (WriterException e) {
            e.printStackTrace();
        }
    }

    /**
     * 二维码解析
     *
     * @param inPath
     *            二维码图片地址
     * @return 二维码文本内容
     */
    public static String qrcodeParse(String inPath) {

        // 文件检测
        if (!new File(inPath).exists()) {
            System.out.println("文件不存在:" + inPath);
            return null;
        }

        String content = "";
        try {

            // 读取图片
            BufferedImage image = ImageIO.read(new File(inPath));
            // 提取图片像素
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            // 二值化(将灰度设置为0或255)
            Binarizer binarizer = new HybridBinarizer(source);
            // 转换为二进制图片
            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);

            // 相关配置
            Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");

            // 解析
            Result result = new MultiFormatReader().decode(binaryBitmap, hints);// 对图像进行解码

            // 获取文本
            content = result.getText();

            // 输出条形码类型(我使用的二维码,所以会输出QR_CODE)
            System.out.println(result.getBarcodeFormat());

        } catch (IOException e) {
            e.printStackTrace();
        } catch (com.google.zxing.NotFoundException e) {
            e.printStackTrace();
        }
        return content;
    }

    /***
     * 一维码生成
     *
     * @param content
     *            文本
     * @param outPath
     *            输出目录
     * @param outName
     *            输出文件名
     * @param format
     *            文件格式
     * @param width
     *            生成图片宽度
     * @param height
     *            生成图片高度
     */
    public static void barCodeBuild(String content, String outPath, String outName, String format, int width,
                                    int height) {

        // 文件检测
        if (!new File(outPath).exists()) {
            new File(outPath).mkdirs();
        }
        Path path = FileSystems.getDefault().getPath(outPath, outName);

        try {
            Code128Writer writer = new Code128Writer();
            BitMatrix matrix = writer.encode(content, BarcodeFormat.CODE_128, width, height);
            MatrixToImageWriter.writeToPath(matrix, format, path);
            System.out.println("调试输出:OK");
        } catch (WriterException | IOException e) {
            e.printStackTrace();
        }
    }
}
